package club.kynb.mall.application.repository.impl;

import club.kynb.mall.application.repository.AuthRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import club.kynb.mall.application.context.MallUserContext;
import club.kynb.mall.application.model.model.dto.TokenDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author kynb_club@163.com
 * @since 2020/12/21 8:54 上午
 */
@Slf4j
@Component
@AllArgsConstructor
public class AuthRepositoryImpl implements AuthRepository {
    private final StringRedisTemplate stringRedisTemplate;
    private final RedisTemplate redisTemplate;
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void saveVerificationCode(String key, String value, Long expire) {
        BoundValueOperations operations = stringRedisTemplate.boundValueOps(key);
        operations.set(value, expire, TimeUnit.SECONDS);
    }

    @Override
    public Optional<String> getVerificationCode(String key) {
        BoundValueOperations operations = stringRedisTemplate.boundValueOps(key);
        return Optional.ofNullable((String) operations.get());
    }

    @Override
    public void clear(String key) {
        BoundValueOperations operations = stringRedisTemplate.boundValueOps(key);
        operations.expire(0, TimeUnit.SECONDS);
    }

    @Override
    public void saveContext(String key, MallUserContext context) {
        final TokenDTO tokenDTO = context.getTokenDTO();
        redisTemplate.opsForValue().set(key, context, tokenDTO.getTokenExpire(), TimeUnit.MINUTES);
    }

    @Override
    public void deleteToken(String shortToken) {
        BoundHashOperations operations = redisTemplate.boundHashOps(shortToken);
        operations.expire(0, TimeUnit.SECONDS);
    }

    @Override
    public Optional<MallUserContext> getContext(String token) {
        //TODO 优化为底层解决
        MallUserContext context = objectMapper.convertValue(redisTemplate.opsForValue().get(token), MallUserContext.class);
        return Optional.ofNullable(context);
    }

}
